home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 014 / amiga3d / joystick.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  11KB  |  458 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <graphics/gfx.h>
  4. #include <devices/gameport.h>
  5. #include <devices/inputevent.h>
  6. #include <intuition/intuition.h>
  7. #include <intuition/intuitionbase.h>
  8. #include "joystick.h"
  9.  
  10. /*#define DEBUG*/
  11. /*#define DEBUGSTATE*/
  12.  
  13. #define MAXNUMEVENTS 2
  14.  
  15. extern LONG IntuitionBase;
  16.  
  17. struct IntuiText ErrorText= {   /* text for error-requester */
  18.     0, 1, JAM1,   /* FrontPen, BackPen, DrawMode */
  19.     10, 10,      /* LeftEdge, TopEdge */
  20.     NULL,      /* ITextFont */
  21.     "3D:   Software Error:", /* IText */
  22.     NULL       /* NextText */
  23. };
  24.  
  25. struct IntuiText AbortMessage= {   /* more text for error-message requester */
  26.     0, 1, JAM1,   /* FrontPen, BackPen, DrawMode */
  27.     11, 45,      /* LeftEdge, TopEdge */
  28.     NULL,      /* ITextFont */
  29.     "Select ABORT to exit", /* IText */
  30.     NULL      /* NextText */
  31. };
  32.  
  33. struct IntuiText ResumeMessage= {   /* more text for error-message requester */
  34.     0, 1, JAM1,   /* FrontPen, BackPen, DrawMode */
  35.     11, 45,      /* LeftEdge, TopEdge */
  36.     NULL,      /* ITextFont */
  37.     "Select RESUME to continue", /* IText */
  38.     NULL      /* NextText */
  39. };
  40.  
  41. struct IntuiText AbortText= {   /* more text for error-requester */
  42.     0, 1, JAM1,   /* FrontPen, BackPen, DrawMode */
  43.     6, 4,      /* LeftEdge, TopEdge */
  44.     NULL,      /* ITextFont */
  45.     "ABORT",      /* IText */
  46.     NULL      /* NextText */ 
  47. };
  48.  
  49. struct IntuiText ResumeText= {   /* more text for error-requester */
  50.     0, 1, JAM1,   /* FrontPen, BackPen, DrawMode */
  51.     6, 4,      /* LeftEdge, TopEdge */
  52.     NULL,      /* ITextFont */
  53.     "RESUME",      /* IText */
  54.     NULL      /* NextText */ 
  55. };
  56.  
  57. extern struct MsgPort *CreatePort();
  58. extern DeletePort();
  59. extern struct IOStdReq *CreateStdIO();      
  60. extern DeleteStdIO();      
  61.  
  62. /******************************************************************************/
  63.  
  64. ULONG set_flags(joystick_data,flags)      
  65. struct InputEvent *joystick_data;
  66. ULONG flags;
  67. {
  68.    SHORT xmove, ymove;
  69.  
  70.    xmove = joystick_data->ie_X;
  71.    ymove = joystick_data->ie_Y;
  72.  
  73.    switch(ymove)
  74.    {
  75.        case(-1):   flags |=  BUTTON_FORWARD;
  76.              flags &= ~BUTTON_BACK;
  77.          break;
  78.        case( 0):   flags &= ~BUTTON_FORWARD;
  79.              flags &= ~BUTTON_BACK;
  80.          break;
  81.        case( 1):   flags &= ~BUTTON_FORWARD;
  82.              flags |=  BUTTON_BACK;
  83.          break;
  84.        default:   break;
  85.    }
  86.  
  87.    switch(xmove)
  88.    {
  89.        case(-1):   flags |=  BUTTON_LEFT;
  90.              flags &= ~BUTTON_RIGHT;
  91.          break;
  92.        case( 0):   flags &= ~BUTTON_LEFT;
  93.              flags &= ~BUTTON_RIGHT;
  94.          break;
  95.        case( 1):   flags &= ~BUTTON_LEFT;
  96.              flags |=  BUTTON_RIGHT;
  97.          break;
  98.        default:   break;
  99.    }
  100.  
  101.    if(joystick_data->ie_Code != IECODE_NOBUTTON)
  102.    {
  103.        if(joystick_data->ie_Code == IECODE_LBUTTON) 
  104.        {
  105.       if (!(flags & ACTION))
  106.       {
  107.           flags |=  BUTTON_DOWN;
  108.           flags &= ~NO_BUTTON;
  109.       }
  110.        }
  111.        if(joystick_data->ie_Code == (IECODE_LBUTTON + IECODE_UP_PREFIX))
  112.        {
  113.       if (!(flags & BUTTON_DOWN))
  114.       {
  115.           flags |=  BUTTON_UP;
  116.           flags &= ~NO_BUTTON; 
  117.       }
  118.       else
  119.       {
  120.           if (!(flags & ACTION))
  121.           {
  122.          flags |=  ACTION;
  123.          flags |=  BUTTON_UP; 
  124.          flags &= ~NO_BUTTON;
  125.           }
  126.           else
  127.           {
  128.          flags |=  BUTTON_UP;
  129.          flags &= ~NO_BUTTON; 
  130.           }
  131.       }
  132.        }
  133.    }
  134.    else
  135.    {
  136.        if (!(flags & ACTION))
  137.        {
  138.       if (!(flags & (BUTTON_DOWN | BUTTON_UP)))
  139.       {
  140.           flags |=  NO_BUTTON;
  141.       }
  142.        }
  143.    }
  144.  
  145.    if (flags & ACTION)
  146.    {
  147.        UBYTE actioncount;
  148.  
  149.        actioncount = ((flags & 0xFF00) >> 8 );
  150.        actioncount += 1;
  151.        flags = ( (flags & 0xFFFF00FF) | (actioncount<<8) );
  152.        flags &= ~BUTTON_DOWN;
  153.        flags &= ~BUTTON_UP;
  154.        flags &= ~ACTION;
  155.    }
  156.  
  157. #ifdef DEBUG
  158.    switch(ymove) 
  159.    {
  160.        case (-1):  switch(xmove)
  161.          {
  162.              case(-1):   
  163. #ifdef DEBUG
  164.                printf("NW");
  165. #endif
  166.                break;
  167.              case( 0):   
  168. #ifdef DEBUG
  169.                printf("N ");
  170. #endif
  171.                break;
  172.              case( 1):   
  173. #ifdef DEBUG
  174.                printf("NE");
  175. #endif
  176.                break;
  177.              default:   break;
  178.          }
  179.          break;
  180.        case ( 0):  switch(xmove)
  181.          {
  182.              case(-1):   
  183. #ifdef DEBUG
  184.                printf(" W");
  185. #endif
  186.                break;
  187.              case( 0):   
  188. #ifdef DEBUG
  189.                printf("  ");
  190. #endif
  191.                break;
  192.              case( 1):   
  193. #ifdef DEBUG
  194.                printf(" E");
  195. #endif
  196.                break;
  197.              default:   break;
  198.          }
  199.          break;
  200.        case ( 1):  switch(xmove)
  201.          {
  202.              case(-1):   
  203. #ifdef DEBUG
  204.                    printf("SW");
  205. #endif
  206.                break;
  207.              case( 0):   
  208. #ifdef DEBUG
  209.                printf("S ");
  210. #endif
  211.                break;
  212.              case( 1):   
  213. #ifdef DEBUG
  214.                printf("SE");
  215. #endif
  216.                break;
  217.              default:   break;
  218.          }
  219.          break;
  220.        default:   break;
  221.    }
  222. #endif
  223.  
  224. #ifdef DEBUG
  225.    if(joystick_data->ie_Code != IECODE_NOBUTTON)
  226.    {
  227.        if(joystick_data->ie_Code == IECODE_LBUTTON) 
  228. #ifdef DEBUG
  229.        printf("!");
  230. #endif
  231.        if(joystick_data->ie_Code == (IECODE_LBUTTON + IECODE_UP_PREFIX))
  232. #ifdef DEBUG
  233.        printf("#");
  234. #endif
  235.    }
  236.    else
  237.    {
  238. #ifdef DEBUG
  239.        /* printf(" "); */
  240. #endif
  241.    }
  242. #endif
  243.  
  244.    return(flags);
  245. }
  246.  
  247. struct IOStdReq *open_joystick()
  248. {
  249.     struct MsgPort *joystick_msg_port;
  250.     struct IOStdReq *joystick_io_request;
  251.     BYTE *joystick_eventbuf;
  252.     struct Message *message;
  253.     LONG error = FALSE;
  254.  
  255. #ifdef DEBUG
  256.     printf("joystick...entering\n");
  257. #endif
  258.  
  259.     if ( (IntuitionBase = OpenLibrary("intuition.library", 31)) == NULL)
  260.     {
  261.    ErrorText.NextText = &AbortMessage;
  262.    AutoRequest(NULL, &ErrorText, NULL, &AbortText, 0, 0, 330, 75);
  263.    exit(0);
  264.     }
  265.  
  266.     /* allocate memory for the joystick event buffer */
  267.  
  268.     if ( (joystick_eventbuf = (BYTE *)AllocMem(sizeof(struct InputEvent)*MAXNUMEVENTS,MEMF_PUBLIC|MEMF_CLEAR)) == NULL)
  269.     {
  270.    ErrorText.NextText = &AbortMessage;
  271.    AutoRequest(NULL, &ErrorText, NULL, &AbortText, 0, 0, 330, 75);
  272.    exit(0);
  273.     }
  274.  
  275.     /* provide a port for the IO request/response */
  276.  
  277.     joystick_msg_port = CreatePort("joystickport",0);   
  278.  
  279.     if(joystick_msg_port == 0)
  280.     {
  281.    ErrorText.NextText = &AbortMessage;
  282.    AutoRequest(NULL, &ErrorText, NULL, &AbortText, 0, 0, 330, 75);
  283.    exit(-1);
  284.     }
  285.  
  286.     /* make an io request block for communicating with the joystick device */
  287.  
  288.     joystick_io_request = CreateStdIO(joystick_msg_port);     
  289.  
  290.     if(joystick_io_request == 0)
  291.     {
  292.    ErrorText.NextText = &AbortMessage;
  293.    AutoRequest(NULL, &ErrorText, NULL, &AbortText, 0, 0, 330, 75);
  294.    DeletePort(joystick_msg_port);
  295.    exit(-2);
  296.     }
  297.  
  298.     /* open the gameport device for access, unit 1 is right port */
  299.  
  300.     if(OpenDevice("gameport.device",1,joystick_io_request,0))
  301.     {
  302.    ErrorText.NextText = &AbortMessage;
  303.    AutoRequest(NULL, &ErrorText, NULL, &AbortText, 0, 0, 330, 75);
  304.    FreeMem(joystick_eventbuf,sizeof(struct InputEvent) * MAXNUMEVENTS);
  305.    DeleteStdIO(joystick_io_request);
  306.    DeletePort(joystick_msg_port);
  307.    exit(-4);
  308.     }
  309.  
  310.     /* set the device type to absolute joystick */
  311.  
  312.     if (set_controller_type(joystick_io_request,GPCT_ABSJOYSTICK) != 0)
  313.     {
  314.    ErrorText.NextText = &AbortMessage;
  315.    AutoRequest(NULL, &ErrorText, NULL, &AbortText, 0, 0, 330, 75);
  316.    FreeMem(joystick_eventbuf,sizeof(struct InputEvent) * MAXNUMEVENTS);
  317.    DeleteStdIO(joystick_io_request);
  318.    DeletePort(joystick_msg_port);
  319.    exit(-4);
  320.     }
  321.  
  322.     /* trigger on button-down, button-up, front, back, left, right, center  */
  323.  
  324.     if (set_controller_trigger(joystick_io_request,GPTF_UPKEYS+GPTF_DOWNKEYS,1,1,1) != 0)
  325.     {
  326.    ErrorText.NextText = &AbortMessage;
  327.    AutoRequest(NULL, &ErrorText, NULL, &AbortText, 0, 0, 330, 75);
  328.    FreeMem(joystick_eventbuf,sizeof(struct InputEvent) * MAXNUMEVENTS);
  329.    DeleteStdIO(joystick_io_request);
  330.    DeletePort(joystick_msg_port);
  331.    exit(-4);
  332.     }
  333.  
  334.     /* SETUP THE IO MESSAGE BLOCK FOR THE ACTUAL DATA READ */
  335.  
  336.     /* gameport.device replies to this task */
  337.     joystick_io_request->io_Message.mn_ReplyPort = joystick_msg_port;
  338.  
  339.     /* from now on, just read input events */
  340.     joystick_io_request->io_Command = GPD_READEVENT;   
  341.     
  342.     /* into the input buffer, one at a time. */
  343.     joystick_io_request->io_Data = joystick_eventbuf;      
  344.  
  345.     /* read num events each time we go back to the joystickport */
  346.     joystick_io_request->io_Length = sizeof(struct InputEvent)* MAXNUMEVENTS;   
  347.  
  348.     return(joystick_io_request);
  349.  
  350. }
  351.  
  352.  
  353. ULONG test_joystick(joystick_io_request,state)
  354. struct IOStdReq *joystick_io_request;
  355. ULONG state;
  356. {
  357.     ULONG flags;
  358.     struct InputEvent *joystick_data;
  359.  
  360.     /* test the joystick */
  361.    
  362.     if (DoIO(joystick_io_request)) return(state);
  363.  
  364.     flags = state;
  365.  
  366.     for (joystick_data = joystick_io_request->io_Data; joystick_data; joystick_data = joystick_data->ie_NextEvent)
  367.     {
  368.    flags = set_flags(joystick_data,flags);   
  369.     }
  370.     state = flags;
  371.  
  372. #ifdef DEBUGSTATE
  373.     printf("\nstate: %4lx",state);
  374. #endif
  375.  
  376.     return(state);
  377.  
  378. }
  379.  
  380.  
  381. close_joystick(joystick_io_request)
  382. struct IOStdReq *joystick_io_request;
  383. {
  384.  
  385.     /* close up joystick device */
  386.     
  387.     CloseDevice(joystick_io_request);
  388.  
  389.     /* clean up */
  390.  
  391.     FreeMem(joystick_io_request->io_Data,sizeof(struct InputEvent) * MAXNUMEVENTS);
  392.     
  393.     DeletePort(joystick_io_request->io_Message.mn_ReplyPort);
  394.  
  395.     DeleteStdIO(joystick_io_request);
  396.  
  397.  
  398. }
  399.  
  400.  
  401. int set_controller_type(ior,type)
  402. struct IOStdReq *ior;
  403. BYTE type;
  404. {
  405.    ior->io_Command = GPD_SETCTYPE;   
  406.    ior->io_Length = 1;
  407.  
  408.    /* set type of controller to "type" */
  409.    ior->io_Data = &type;
  410.  
  411. #ifdef DEBUG
  412.    printf("joystick:set_controller_type\n");
  413. #endif
  414.    return(DoIO(ior));
  415. }
  416.  
  417. int set_controller_trigger(ior,keys,timeout,xdelta,ydelta)
  418. struct IOStdReq *ior;
  419. UWORD keys,timeout,xdelta,ydelta;
  420. {
  421.    struct GamePortTrigger gpt;
  422.  
  423.    ior->io_Command = GPD_SETTRIGGER;   
  424.    ior->io_Length = sizeof(gpt);
  425.    ior->io_Data = &gpt;
  426.    gpt.gpt_Keys = keys;
  427.    gpt.gpt_Timeout = timeout;
  428.    gpt.gpt_XDelta = xdelta;
  429.    gpt.gpt_YDelta = ydelta;
  430.  
  431. #ifdef DEBUG
  432.    printf("joystick:set_controller_trigger\n");
  433. #endif
  434.    return(DoIO(ior));
  435. }
  436.  
  437. /*
  438. main()
  439. {
  440.     ULONG state = 0;
  441.     struct IOStdReq *ior;
  442.  
  443.     if ((ior = open_joystick()) == NULL)
  444.     {
  445.    exit(-1);
  446.     }
  447.     else
  448.     {
  449.        while ( ( (state & 0xFF00) >> 8 ) != 0xF )
  450.        {
  451.        state = test_joystick(ior,state);      
  452.        }
  453.        close_joystick(ior);
  454.     }
  455.     exit(0);
  456. }
  457. */
  458.